! Copyright (c) 2025 ZUO Zhihua (zuo.zhihua@qq.com)
!
! Permission is hereby granted, free of charge, to any person obtaining a copy of
! this software and associated documentation files (the "Software"), to deal in
! the Software without restriction, including without limitation the rights to
! use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
! the Software, and to permit persons to whom the Software is furnished to do so,
! subject to the following conditions:
!
! The above copyright notice and this permission notice shall be included in all
! copies or substantial portions of the Software.
!
! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
! IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
! FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
! COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
! IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
! CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

!> 时间计时模块
!> 提供计时器功能和时间格式化工具
!>
!> 主要功能:
!> - timer_type: 48天计时器类型,用于精确计时
!> - nowtime: 获取当前系统时间,格式为 YYYY-MM-DD HH:MM:SS.SSS
!> - sec2dhm: 将秒数转换为天时分格式 HH:MM:SS.SSS (+DD days)
!> - timer: 全局计时器实例
module timer_module

  implicit none
  private

  public :: timer_type, nowtime, sec2dhm, timer

  !> 48 天计时器
  type timer_type
    integer, private :: seed
  contains
    procedure :: tic, toc
  end type timer_type

  type(timer_type) :: timer

contains

  !> 开始计时
  subroutine tic(self)
    class(timer_type), intent(out) :: self

    call system_clock(self%seed)

  end subroutine tic

  !> 结束计时
  real function toc(self)
    class(timer_type), intent(in) :: self
    integer :: time_now, time_rate, time_max

    call system_clock(time_now, time_rate, time_max)
    toc = time_now - self%seed
    if (toc < 0) then
      toc = toc + time_max  ! clock cycled
    end if

    toc = real(toc) / time_rate

  end function toc

  !> 将秒数转换为天时分
  pure character(22) function sec2dhm(sec) result(dhm)
    real, intent(in) :: sec
    integer :: d, h, m, s
    real :: sec_local

    d = int(sec / 86400.0)
    sec_local = sec - d * 86400.0
    h = int((sec_local) / 3600.0)
    sec_local = sec_local - h * 3600.0
    m = int(sec_local / 60.0)
    sec_local = sec_local - m * 60.0
    s = int(sec_local)
    sec_local = sec_local - s
    write (dhm, '(i2.2, ":", i2.2, ":", i2.2, ".", i3.3, " (+", i2.2, "days)")') h, m, s, nint(sec_local * 1000.0), d

  end function sec2dhm

  !> 获取当前时间
  character(23) function nowtime() result(t)
    character(len=8) :: datstr
    character(len=10) :: timstr

    call date_and_time(datstr, timstr)
    t = datstr(1:4)//"-"//datstr(5:6)//"-"//datstr(7:8)//" "//timstr(1:2)//":"//timstr(3:4)//":"//timstr(5:10)

  end function nowtime

end module timer_module
